﻿using FluentValidation;
using Mes.Application.Common;
using Mes.Application.DTO.Inputs.WorkOrders;
using Mes.Application.DTO.Results.WorkOrders;
using Mes.Application.Services.WorkOrders;
using Mes.Application.Web.Validators.WorkOrders;
using Mes.Domain.BoundedContext;
using Microsoft.AspNetCore.Mvc;

namespace Mes.Application.Web.Controllers.WorkOrders
{
    /// <summary>
    /// 工单流转控制器
    /// </summary>
    [ApiController]
    [Route("/api/v1")]
    public class WoFlowController : ControllerBase
    {
        private readonly IWoFlowService _woFlowService;
        private readonly ILogger<WoFlowController> _logger;
        private readonly IValidator<AddingItemProdInput> _addingItemProdInputValidator;
        private readonly IValidator<ReducingItemProdInput> _reducingItemProdInputValidator;
        private readonly IValidator<AddingItemConsInput> _addingItemConsInputValidator;
        private readonly IValidator<StartingJobStepInput> _startingJobStepInputValidator;
        private readonly IValidator<StoppingJobStepInput> _stoppingJobStepInputValidator;
        private readonly IValidator<ReadyingJobInput> _readyingJobInputValidator;
        private readonly IValidator<RunningJobInput> _runningJobInputValidator;
        private readonly IValidator<PausingJobInput> _pausingJobInputValidator;
        private readonly IValidator<EndingJobInput> _endingJobInputValidator;
        /// <summary>
        /// 工单流转控制器
        /// </summary>
        /// <param name="woFlowService">工单流转服务</param>
        /// <param name="logger">日志</param>
        /// <param name="addingItemProdInputValidator">添加产量验证器</param>
        /// <param name="reducingItemProdInputValidator">减少产量验证器</param>
        /// <param name="addingItemConsInputValidator">添加消耗量验证器</param>
        /// <param name="startingJobStepInputValidator">启动工步（工步状态由Ready->Running）验证器</param>
        /// <param name="stoppingJobStepInputValidator">停止工步（工步状态由Running->Complete或者工步状态由Complete->SUPERSEDED）验证器</param>
        /// <param name="readyingJobInputValidator">作业-准备生产验证器</param>
        /// <param name="runningJobInputValidator">作业-运行所选作业验证器</param>
        /// <param name="pausingJobInputValidator">作业-暂停验证器</param>
        /// <param name="endingJobInputValidator">作业-完成验证器</param>
        public WoFlowController(IWoFlowService woFlowService,ILogger<WoFlowController> logger, IValidator<AddingItemProdInput> addingItemProdInputValidator, IValidator<ReducingItemProdInput> reducingItemProdInputValidator, IValidator<AddingItemConsInput> addingItemConsInputValidator, IValidator<StartingJobStepInput> startingJobStepInputValidator, IValidator<StoppingJobStepInput> stoppingJobStepInputValidator, IValidator<ReadyingJobInput> readyingJobInputValidator, IValidator<RunningJobInput> runningJobInputValidator, IValidator<PausingJobInput> pausingJobInputValidator, IValidator<EndingJobInput> endingJobInputValidator)
        {
            _woFlowService = woFlowService;
            _logger = logger;
            _addingItemProdInputValidator = addingItemProdInputValidator;
            _reducingItemProdInputValidator = reducingItemProdInputValidator;
            _addingItemConsInputValidator = addingItemConsInputValidator;
            _startingJobStepInputValidator = startingJobStepInputValidator;
            _stoppingJobStepInputValidator = stoppingJobStepInputValidator;
            _readyingJobInputValidator = readyingJobInputValidator;
            _runningJobInputValidator = runningJobInputValidator;
            _pausingJobInputValidator = pausingJobInputValidator;
            _endingJobInputValidator = endingJobInputValidator;
        }

        /// <summary>
        /// 添加产量
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("itemprod")]
        public async Task<ActionResult> AddItemProdAsync([FromBody] AddingItemProdInput input)
        {
            try
            {
                var result = await _addingItemProdInputValidator.ValidateAsync(input);
                if (!result.IsValid)
                {
                    return BadRequest(result.Errors.First().ErrorMessage);
                }
                await _woFlowService.AddItemProdAsync(input);
                return Ok();
            }
            catch (CustomException ex)
            {
                _logger.LogError(ex.Message, ex);
                return BadRequest(ex.Message);
            }
        }

        /// <summary>
        /// 减少产量
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("itemprod/reduce")]
        public async Task<ActionResult> ReduceItemProdAsync([FromBody] ReducingItemProdInput input)
        {
            try
            {
                var result = await _reducingItemProdInputValidator.ValidateAsync(input);
                if (!result.IsValid)
                {
                    return BadRequest(result.Errors.First().ErrorMessage);
                }
                await _woFlowService.ReduceItemProdAsync(input);
                return Ok();
            }
            catch (CustomException ex)
            {
                _logger.LogError(ex.Message, ex);
                return BadRequest(ex.Message);
            }
        }

        /// <summary>
        /// 查询存在job的实体列表
        /// </summary>
        /// <returns></returns>
        [HttpGet("withjobs/ents")]
        public async Task<ActionResult<ItemsResult<IdNameResult>>> GetEntitiesWithJobsAsync()
        {
            try
            {
                var result = await _woFlowService.GetEntitiesWithJobsAsync();
                return Ok(result);
            }
            catch (CustomException ex)
            {
                _logger.LogError(ex.Message, ex);
                return BadRequest(ex.Message);
            }
        }
        /// <summary>
        /// 查询指定实体所有作业
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpGet("ent/jobs")]
        public async Task<ActionResult<ItemsResult<EntJobsResult>>> GetEntJobsAsync([FromQuery] GettingEntJobsInput input)
        {
            try
            {
                var result=  await _woFlowService.GetEntJobsAsync(input);
                return Ok(result);
            }
            catch (CustomException ex)
            {
                _logger.LogError(ex.Message, ex);
                return BadRequest(ex.Message);
            }
        }

        /// <summary>
        /// 查询运行作业的产量、物料清单、工步
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpGet("job/prods/boms/steps")]
        public async Task<ActionResult<RunningJobProdBOMStepResult>> GetEntJobsAsync([FromQuery] GettingRunningJobProdsBOMsStepsInput input)
        {
            try
            {
                var result = await _woFlowService.GetRunningJobProdsBOMsStepsAsync(input.Wo_Id,input.Oper_Id);
                return Ok(result);
            }
            catch (CustomException ex)
            {
                _logger.LogError(ex.Message, ex);
                return BadRequest(ex.Message);
            }
        }

        /// <summary>
        /// 添加消耗量
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("itemcons")]
        public async Task<ActionResult> AddItemConsAsync([FromBody] AddingItemConsInput input)
        {
            try
            {
                var result = await _addingItemConsInputValidator.ValidateAsync(input);
                if (!result.IsValid)
                {
                    return BadRequest(result.Errors.First().ErrorMessage);
                }
                await _woFlowService.AddItemConsAsync(input);
                return Ok();
            }
            catch (CustomException ex)
            {
                _logger.LogError(ex.Message, ex);
                return BadRequest(ex.Message);
            }
        }

        /// <summary>
        /// 启动工步（工步状态由Ready->Running）
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("jobstep/start")]
        public async Task<ActionResult> StartJobStepAsync([FromBody] StartingJobStepInput input)
        {
            try
            {
                var result = await _startingJobStepInputValidator.ValidateAsync(input);
                if (!result.IsValid)
                {
                    return BadRequest(result.Errors.First().ErrorMessage);
                }
                await _woFlowService.StartJobStepAsync(input);
                return Ok();
            }
            catch (CustomException ex)
            {
                return BadRequest(ex.Message);
            }
           
        }

        /// <summary>
        /// 停止工步（工步状态由Running->Complete或者工步状态由Complete->SUPERSEDED,或者SUPERSEDED->Complete）
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("jobstep/stop")]
        public async Task<ActionResult> StopJobStepAsync([FromBody] StoppingJobStepInput input)
        {
            try
            {
                var result = await _stoppingJobStepInputValidator.ValidateAsync(input);
                if (!result.IsValid)
                {
                    return BadRequest(result.Errors.First().ErrorMessage);
                }
                await _woFlowService.StopJobStepAsync(input);
                return Ok();
            }
            catch (CustomException ex)
            {
                return BadRequest(ex.Message);
            }
        }

        /// <summary>
        /// 作业-准备生产
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("job/ready")]
        public async Task<ActionResult> ReadyJobAsync([FromBody] ReadyingJobInput input)
        {
            try
            {
                var result = await _readyingJobInputValidator.ValidateAsync(input);
                if (!result.IsValid)
                {
                    return BadRequest(result.Errors.First().ErrorMessage);
                }
                await _woFlowService.ReadyJobAsync(input);
                return Ok();
            }
            catch (CustomException ex)
            {
                return BadRequest(ex.Message);
            }
        }

        /// <summary>
        /// 作业-运行所选作业
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("job/run")]
        public async Task<ActionResult> RunJobAsync([FromBody] RunningJobInput input)
        {
            try
            {
                var result = await _runningJobInputValidator.ValidateAsync(input);
                if (!result.IsValid)
                {
                    return BadRequest(result.Errors.First().ErrorMessage);
                }
                await _woFlowService.RunJobAsync(input);
                return Ok();
            }
            catch (CustomException ex)
            {
                return BadRequest(ex.Message);
            }
        }

        /// <summary>
        /// 作业-暂停
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("job/pause")]
        public async Task<ActionResult> PauseJobAsync([FromBody] PausingJobInput input)
        {
            try
            {
                var result = await _pausingJobInputValidator.ValidateAsync(input);
                if (!result.IsValid)
                {
                    return BadRequest(result.Errors.First().ErrorMessage);
                }
                await _woFlowService.PauseJobAsync(input);
                return Ok();
            }
            catch (CustomException ex)
            {
                return BadRequest(ex.Message);
            }
        }

        /// <summary>
        /// 作业-完成
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost("job/end")]
        public async Task<ActionResult> EndJobAsync([FromBody] EndingJobInput input)
        {
            try
            {
                var result = await _endingJobInputValidator.ValidateAsync(input);
                if (!result.IsValid)
                {
                    return BadRequest(result.Errors.First().ErrorMessage);
                }
                await _woFlowService.EndJobAsync(input);
                return Ok();
            }
            catch (CustomException ex)
            {
                return BadRequest(ex.Message);
            }
        }
    }
}
